<?php
/**
 * ExaminationType Service.
 * User: Administrator
 * Date: 2020/2/13 0013
 * Time: 下午 2:02
 */
namespace app\api\service\common;

use WxPayConfig;
use app\api\model\payment\PayNotify;
use app\api\model\order\Order;
require_once '../extend/wxpay/lib/WxPay.Api.php';
require_once '../extend/wxpay/lib/WxPay.Notify.php';

Class Notify extends \WxPayNotify {

    /**
     * 小程序支付回调
     */
    public function xcx()
    {
        $config = new WxPayConfig();
        $this->Handle($config, false);

    }

    //重写回调处理函数
    /**
     * @param WxPayNotifyResults $data 回调解释出的参数
     * @param WxPayConfigInterface $config
     * @param string $msg 如果回调处理失败，可以将错误信息输出到该方法
     * @return boolean true回调出来完成不需要继续回调，false回调处理未完成需要继续回调
     */
    public function NotifyProcess($objData, $config, &$msg)
    {
        $data = $objData->GetValues();
        //TODO 1、进行参数校验
        if(!array_key_exists("return_code", $data)
            ||(array_key_exists("return_code", $data) && $data['return_code'] != "SUCCESS")) {
            //TODO失败,不是支付成功的通知
            //如果有需要可以做失败时候的一些清理处理，并且做一些监控
            $msg = "异常异常";
            $this->create($data, '此订单回调不是支付成功的通知', $data['out_trade_no']??'' );
            return false;
        }
        if(!array_key_exists("transaction_id", $data)){
            $msg = "输入参数不正确";
            $this->create($data, '此订单没有微信支付订单号', $data['out_trade_no']??'' );
            return false;
        }
        //TODO 2、进行签名验证
        $checkResult = $objData->CheckSign($config);
        if($checkResult == false){
            //签名错误
            $msg = "签名错误...";
            $this->create($data, '签名验证失败', $data['out_trade_no']??'' );
            return false;
        }
        //查询订单，判断订单真实性
        if(!$this->Queryorder($data["transaction_id"])){
            $msg = "订单查询失败";
            $this->create($data, '微信第三方平台不存在此订单', $data['out_trade_no']??'' );
            return false;
        }
        // 处理订单支付状态
        $order = Order::where('order_number', $data['out_trade_no'])->findOrEmpty();
        if ( $order->isEmpty() ) {
            $msg = "在本平台未查询到订单";
            $this->create($data, '未查询到订单', $data['out_trade_no']??'' );
            return false;
        }
        if ( $data['total_fee']*100 != $order->price ) {
            $msg = "订单金额有误";
            $this->create($data, '订单金额有误', $data['out_trade_no']??'' );
            return false;
        }
        $order->api_ordernumber = $data['transaction_id'];
        $order->payment_status = 1;
        $order->payment_at = date("Y-m-d H:i:s");
        if ( $order->save() === false ) {
            $msg = "服务错误";
            $this->create($data, '数据库更改状态时失败', $data['out_trade_no']??'' );
            return false;
        }
        return true;
    }

    //查询订单
    public function Queryorder($transaction_id)
    {
        $input = new \WxPayOrderQuery();
        $input->SetTransaction_id($transaction_id);

        $config = new WxPayConfig();
        $result = \WxPayApi::orderQuery($config, $input);
        Log::DEBUG("query:" . json_encode($result));
        if(array_key_exists("return_code", $result)
            && array_key_exists("result_code", $result)
            && $result["return_code"] == "SUCCESS"
            && $result["result_code"] == "SUCCESS")
        {
            return true;
        }
        return false;
    }

    /**
     * 记录订单异常
     * @param string $order_number
     * @param string $msg
     * @param mixed $data 数据包
     * @return bool
     */
    public function create($data, string $msg='', string $order_number='')
    {
        return PayNotify::create([
            'order_number' => $order_number,
            'err_msg' => $msg,
            'data' => json_encode($data)
        ]);
    }

}